<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>

<head>
<title>Carousel Component Example - Spotlight &amp; Preview</title>
	<meta http-equiv="content-type" content="text/html; charset=UTF-8">
	<script type="text/javascript" src="http://yui.yahooapis.com/combo?2.6.0/build/utilities/utilities.js&2.6.0/build/container/container_core-min.js"></script> 
	<script type="text/javascript" src="scripts/carousel.js"></script>

	<link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/combo?2.6.0/build/reset-fonts-grids/reset-fonts-grids.css&2.6.0/build/base/base-min.css">
	<link href="css/carousel.css" rel="stylesheet" type="text/css">
	<link href="css/yui.css" rel="stylesheet" type="text/css">
<!-- 
	Inlined styles for my overrides to the carousel for this demo.
	Normally I would put this in a separate CSS file.
-->
<style type="text/css">
.carousel-component {
	padding:0px;
}
.carousel-component .carousel-list li { 
	margin:4px;
	width:85px; /* img width is 75 px from flickr + a.border-left (1) + a.border-right(1) + 
	               img.border-left (1) + img.border-right (1) + a.margin (6)*/
	/*	margin-left: auto;*/ /* for testing IE auto issue */
}

.carousel-component .carousel-list li a { 
	display:block;
	margin:3px;
	border:1px solid #e2edfa;
	outline:none;
	-moz-outline:none; 
}

.carousel-component .carousel-list li a:hover { 
	border: 1px solid #87bf4e; 
}

.carousel-component .carousel-list li img { 
	border:1px solid #999;
	display:block; 
	margin:4px 0px 0px 4px;
}

.carousel-component .carousel-list li strong { 
	display:block; 
}
									

#prev-arrow { 
	position:absolute;
	top:40px;
	z-index:3;
	cursor:pointer; 
	left:5px; 
}

#next-arrow { 
	position:absolute;
	top:40px;
	z-index:3;
	cursor:pointer; 
	right:5px; 
}

.spotlight {
	border: 1px solid #2222ff;
	filter: alpha(opacity=100); -moz-opacity:1.0;
}

.non-spotlight {
	border: 1px solid #e2edfa;
	filter: alpha(opacity=60); -moz-opacity:0.6;
}

#preview {
	margin: 20px 100px 0px 0px;
	padding:4px;
	clear:both;
}

#preview img {
	border: 1px solid gray;
	padding:4px;
}

pre {
	font-size:10px;
}

</style>

<script type="text/javascript">

var priorCenterItem = 1;

/**
 * Image src URLs
 **/
var imageList = [
				 "http://static.flickr.com/116/268249561_a32393f6ac_s.jpg",
				 "http://static.flickr.com/97/268249177_d0f53c75ae_s.jpg",
				 "http://static.flickr.com/91/268249048_67b9ecb504_s.jpg",
				 "http://static.flickr.com/101/268248936_9cbaffeb08_s.jpg",
				 "http://static.flickr.com/96/268248678_24c0a48e71_s.jpg",
				 "http://static.flickr.com/106/268248583_f781f44205_s.jpg",
				 "http://static.flickr.com/106/268248481_ca3ee38e1e_s.jpg",
				 "http://static.flickr.com/113/268248145_b12fbb7413_s.jpg",
				 "http://static.flickr.com/106/268248063_3aa0e9f801_s.jpg",
				 "http://static.flickr.com/85/268247010_f9e4e0d0a2_s.jpg",
				 "http://static.flickr.com/92/268246360_cd1dc9269e_s.jpg",
				 "http://static.flickr.com/114/268246264_150b9f97a5_s.jpg",
				 "http://static.flickr.com/84/268245733_bdf9efb167_s.jpg",
				 "http://static.flickr.com/86/268245514_0eac3b5e2d_s.jpg",
				 "http://static.flickr.com/96/268245042_76622df01e_s.jpg",
				 "http://static.flickr.com/92/268244677_a45258db84_s.jpg",
				 "http://static.flickr.com/92/268244474_2f3393ee8c_s.jpg",
				 "http://static.flickr.com/105/268244323_e5f0fa4103_s.jpg"
				 ];
var urlList = [
				 "http://static.flickr.com/116/268249561_a32393f6ac_m.jpg",
				 "http://static.flickr.com/97/268249177_d0f53c75ae_m.jpg",
				 "http://static.flickr.com/91/268249048_67b9ecb504_m.jpg",
				 "http://static.flickr.com/101/268248936_9cbaffeb08_m.jpg",
				 "http://static.flickr.com/96/268248678_24c0a48e71_m.jpg",
				 "http://static.flickr.com/106/268248583_f781f44205_m.jpg",
				 "http://static.flickr.com/106/268248481_ca3ee38e1e_m.jpg",
				 "http://static.flickr.com/113/268248145_b12fbb7413_m.jpg",
				 "http://static.flickr.com/106/268248063_3aa0e9f801_m.jpg",
				 "http://static.flickr.com/85/268247010_f9e4e0d0a2_m.jpg",
				 "http://static.flickr.com/92/268246360_cd1dc9269e_m.jpg",
				 "http://static.flickr.com/114/268246264_150b9f97a5_m.jpg",
				 "http://static.flickr.com/84/268245733_bdf9efb167_m.jpg",
				 "http://static.flickr.com/86/268245514_0eac3b5e2d_m.jpg",
				 "http://static.flickr.com/96/268245042_76622df01e_m.jpg",
				 "http://static.flickr.com/92/268244677_a45258db84_m.jpg",
				 "http://static.flickr.com/92/268244474_2f3393ee8c_m.jpg",
				 "http://static.flickr.com/105/268244323_e5f0fa4103_m.jpg"
				 ];

var lastRan = -1;

/**
 * Since carousel.addItem uses an HTML string to create the interface
 * for each carousel item, this method formats the HTML for an LI.
 **/

var fmtItem = function(imgUrl, url, title, i) {
  	var innerHTML = 
  		'<img id="carousel-image-' + i + '" src="' + 
  		imgUrl +
		'" width="' +
		75 +
		'" height="' +
		75+
		'"/><a id="carousel-anchor-' + i + '" href="' + 
  		url + 
  		'">' + 
  		title + '<\/a>';
  
	return innerHTML;
	
};

/**
 * Custom inital load handler. Called when the carousel loads the initial
 * set of data items. Specified to the carousel as the configuration
 * parameter: loadInitHandler
 **/
var loadInitialItems = function(type, args) {
	var start = args[0];
	var last = args[1]; 

	load(this, start, last);
	spotlight(this);	
	preview(this);
};

/**
 * Custom load next handler. Called when the carousel loads the next
 * set of data items. Specified to the carousel as the configuration
 * parameter: loadNextHandler
 **/
var loadNextItems = function(type, args) {
	// get the last middle item and turn off spotlight
	var li = this.getItem(priorCenterItem);
	
	var start = args[0];
	var last = args[1]; 
	var alreadyCached = args[2];

	if(!alreadyCached) {
		load(this, start, last);
	}
	spotlight(this);
	preview(this);
};

/**
 * Custom load previous handler. Called when the carousel loads the previous
 * set of data items. Specified to the carousel as the configuration
 * parameter: loadPrevHandler
 **/

var loadPrevItems = function(type, args) {
	// get the last middle item and turn off spotlight
	var li = this.getItem(priorCenterItem);

	var start = args[0];
	var last = args[1]; 
	var alreadyCached = args[2];
	
	if(!alreadyCached) {
		load(this, start, last);
	}
	spotlight(this);
	preview(this);
};

var load = function(carousel, start, last) {

	for(var i=start;i<=last;i++) {
		var randomIndex = getRandom(18, lastRan);
		lastRan = randomIndex;
		carousel.addItem(i, fmtItem(imageList[randomIndex], urlList[randomIndex], "Number " + i, i), 'non-spotlight');
		
		// Image click will scroll to the corresponding carousel item.
		YAHOO.util.Event.addListener('carousel-image-'+i, 'click', function(evt) {
			this.carousel.scrollTo(this.index-2);
		}, {carousel:carousel,index:i}, true);
/*
		// Example of an alternate way to add an item (passing an element instead of html string)
		var p = document.createElement("P");
		var t = document.createTextNode("Item"+i);
		p.appendChild(t);
		carousel.addItem(i, p );
*/
	}
};

var getRandom = function(max, last) {
	var randomIndex;
	do {
		randomIndex = Math.floor(Math.random()*max);
	} while(randomIndex == last);
	
	return randomIndex;
};

/**
 * Custom button state handler for enabling/disabling button state. 
 * Called when the carousel has determined that the previous button
 * state should be changed.
 * Specified to the carousel as the configuration
 * parameter: prevButtonStateHandler
 **/
var handlePrevButtonState = function(type, args) {

	var enabling = args[0];
	var leftImage = args[1];
	if(enabling) {
		leftImage.src = "images/left-enabled.gif";	
	} else {
		leftImage.src = "images/left-disabled.gif";
	}
	
};

/**
 * Custom button state handler for enabling/disabling button state. 
 * Called when the carousel has determined that the next button
 * state should be changed.
 * Specified to the carousel as the configuration
 * parameter: nextButtonStateHandler
 **/
var handleNextButtonState = function(type, args) {

	var enabling = args[0];
	var rightImage = args[1];
	if(enabling) {
		rightImage.src = "images/right-enabled.gif";	
	} else {
		rightImage.src = "images/right-disabled.gif";
	}
	
};

function completeHandler(type, args) {
	// instead of doing the preview in the loadNext and loadPrev you can
	// wait for the animation scroll to stop before showing the preview
	//preview(this);
}
function preview(carousel) {
	var firstVisible = carousel.getProperty("firstVisible");
	var middle = firstVisible + 2;
	
	var anchor = YAHOO.util.Dom.get('carousel-anchor-' + middle);
	YAHOO.util.Dom.get('preview').innerHTML = '<img src="' + anchor.href + '"/>';
}

function spotlight(carousel) {
	var firstVisible = carousel.getProperty("firstVisible");
	var start = firstVisible;
	var revealAmount = carousel.getProperty("revealAmount");
	var size = carousel.getProperty("size");
	
	if(revealAmount && firstVisible > 1) {
		start = firstVisible - 1;
	}
	var lastVisible = firstVisible + carousel.getProperty("numVisible") - 1;
	var end = lastVisible;
	if(revealAmount && lastVisible < size) {
		end = lastVisible + 1;
	}
	
	var middle = firstVisible + 2;
	
	for(var i=start; i<=end; i++) {
		var li = carousel.getItem(i);
		
		if(i == middle) {
			YAHOO.util.Dom.replaceClass(li, 'non-spotlight', 'spotlight');
			priorCenterItem = i;
		} else {
			YAHOO.util.Dom.replaceClass(li, 'spotlight', 'non-spotlight');
		}
	}
}

/**
 * You must create the carousel after the page is loaded since it is
 * dependent on an HTML element (in this case 'dhtml-carousel'.) See the
 * HTML code below.
 **/

var carousel; // for ease of debugging; globals generally not a good idea
var pageLoad = function() 
{
	carousel = new YAHOO.extension.Carousel("dhtml-carousel", 
		{
			numVisible:         5,
			animationSpeed:     0.6,
			animationMethod:    YAHOO.util.Easing.backBoth,
			scrollInc:          1,
			navMargin:          40,
			scrollBeforeAmount: 2,
			firstVisible:       -1,
			size:               15,
			scrollAfterAmount:  2,
			prevElement:        "prev-arrow",
			nextElement:        "next-arrow",
			loadInitHandler:    loadInitialItems,
			loadNextHandler:    loadNextItems,
			loadPrevHandler:    loadPrevItems,
			prevButtonStateHandler:   handlePrevButtonState,
			nextButtonStateHandler:   handleNextButtonState,
			animationCompleteHandler: completeHandler
		}
	);
	
	//carousel.loadNextHandlerEvt.subscribe(beforeNext, carousel);
};

YAHOO.util.Event.addListener(window, 'load', pageLoad);


</script>
</head>

<body>

<div id="doc" class="yui-t7">
   <div id="hd">
		<h1>Spotlight &amp; Preview - Carousel</h1>
   </div>
<div id="bd">
<p>Illustrates how to spotlight the middle item in the carousel. Several techniques illustrated:</p>
<ul>
	<li>Highlight the middle item by switching between a style class 'non-spotlight' (all other visible
		items have this class) with the style class 'spotlight')</li>
	<li>To accomplish the offset start (so that item 1 starts in the middle) set <em>scrollBeforeAmount</em> to 2 and <em>scrollAfterAmount</em> to 2. This will allow scrolling between -1 and 17, yet loads only happen from 1 to 15 (size). Also the <em>firstVisible</em> is set to -1.</li>
	<li>The slight bounce is accomplished by setting the <em>animationMethod</em> to <strong>YAHOO.util.Easing.backBoth</strong>.</li>
	<li>carousel.addItem() now allows a third parameter: itemClass that we initially set to 'non-spotlight'</li>
	<li>When the user hits next or previous we turn off the spotlight (switching classes) for the previous
		middle (which is actually the previous firstVisible -- carousel.priorFirstVisible) and highlight the new one</li>
	<li>Clicking on an image in the carousel will scroll to the item and show it in the preview.</li>
</ul>
<p>The full configuration for this carousel is:</p>
<pre>
	carousel = new YAHOO.extension.Carousel("dhtml-carousel", 
		{
			numVisible:         5,
			animationSpeed:     0.6,
			animationMethod:    YAHOO.util.Easing.backBoth,
			scrollInc:          1,
			navMargin:          40,
			scrollBeforeAmount: 2,
			firstVisible:       -1,
			size:               15,
			scrollAfterAmount:  2,
			prevElement:        "prev-arrow",
			nextElement:        "next-arrow",
			loadInitHandler:    loadInitialItems,
			loadNextHandler:    loadNextItems,
			loadPrevHandler:    loadPrevItems,
			prevButtonStateHandler:   handlePrevButtonState,
			nextButtonStateHandler:   handleNextButtonState,
			animationCompleteHandler: completeHandler
		}
	);
	</pre>

<!-- Carousel Structure -->
<div id="dhtml-carousel" class="carousel-component">
	<div><img id="prev-arrow" class="left-button-image" src="images/left-enabled.gif" alt="Previous Button"/>
	</div>
	<div><img id="next-arrow" class="right-button-image" src="images/right-enabled.gif" alt="Next Button"/>
	</div>
	<div class="carousel-clip-region">
		<ul class="carousel-list">
			<!-- Filled in via the loadInitHandler, loadNextHandler, and loadPrevHandler
			<li id="item-1">
			<a href="#">
				<img src="http://static.flickr.com/74/162582364_7fc3e2d60d_s.jpg"/>
			</a>Number One</li>
			-->
		</ul>
	</div>
</div>
<div id="preview"></div>
<div style="padding-top:20px;">View the <a href="source.php?url=carousel_spotlight.html">source</a>&nbsp;or&nbsp;<a href="index.html">documentation</a></div>

</div>
</div> 

</body>
</html>